/**
 * 数据绑定通用Composable
 * 为Vue组件提供统一的数据绑定功能
 */

import { ref, computed, watch, onMounted, onUnmounted } from 'vue';
import { useRealtimeDataStore } from '@/stores/realtime-data';
import type { IDataBindingConfig } from '@/components/mt-edit/store/types';
import { getCachedTransform } from '@/utils/data-cache';

export interface UseDataBindingOptions {
  /**
   * 数据绑定配置
   */
  bindingConfig: IDataBindingConfig;

  /**
   * 组件属性对象的引用
   */
  props: Record<string, any>;

  /**
   * 属性更新回调函数
   */
  onPropertyUpdate?: (property: string, value: any) => void;

  /**
   * 组件唯一标识符（用于订阅管理）
   */
  componentId?: string;
}

export function useDataBinding(options: UseDataBindingOptions) {
  const {
    bindingConfig,
    props,
    onPropertyUpdate,
    componentId = `binding-${Math.random().toString(36).substr(2, 9)}`
  } = options;

  const realtimeStore = useRealtimeDataStore();

  // 当前数据值
  const currentValue = ref<any>(null);
  // 连接状态
  const isConnected = ref(false);
  // 最后更新时间
  const lastUpdateTime = ref<number>(0);

  /**
   * 数据转换函数 - 集成缓存优化
   */
  const transformValue = (value: any): any => {
    if (value === null || value === undefined) {
      return bindingConfig.defaultValue || null;
    }

    // 使用缓存优化数据转换
    const cacheKey = `transform-${bindingConfig.transform || 'none'}-${componentId}`;

    return getCachedTransform(cacheKey, value, (rawValue) => {
      try {
        switch (bindingConfig.transform) {
          case 'number':
            return Number(rawValue);

          case 'string':
            return String(rawValue);

          case 'boolean':
            return Boolean(rawValue);

          case 'visibility':
            // 专门用于显示/隐藏的转换
            const boolValue = Boolean(rawValue);
            // 返回CSS display值
            return boolValue ? '' : 'none';

          case 'decimal2':
            return Number(Number(rawValue).toFixed(2));

          case 'percentage':
            return Number(rawValue) * 100;

          case 'array':
            // 确保返回数组类型
            if (Array.isArray(rawValue)) {
              return rawValue;
            }
            // 如果是字符串，尝试JSON解析
            if (typeof rawValue === 'string') {
              try {
                const parsed = JSON.parse(rawValue);
                return Array.isArray(parsed) ? parsed : [rawValue];
              } catch {
                return [rawValue];
              }
            }
            // 如果是对象，转换为数组
            if (typeof rawValue === 'object') {
              return Object.values(rawValue);
            }
            return [rawValue];

          case 'object':
            // 确保返回对象类型
            if (typeof rawValue === 'object' && !Array.isArray(rawValue)) {
              return rawValue;
            }
            // 如果是字符串，尝试JSON解析
            if (typeof rawValue === 'string') {
              try {
                const parsed = JSON.parse(rawValue);
                return typeof parsed === 'object' ? parsed : { value: rawValue };
              } catch {
                return { value: rawValue };
              }
            }
            // 如果是数组，转换为对象
            if (Array.isArray(rawValue)) {
              const obj: any = {};
              rawValue.forEach((item, index) => {
                obj[index] = item;
              });
              return obj;
            }
            return { value: rawValue };

          case 'json':
            // JSON解析，保持原始结构
            if (typeof rawValue === 'string') {
              try {
                return JSON.parse(rawValue);
              } catch {
                return rawValue;
              }
            }
            return rawValue;

          case 'custom':
            if (bindingConfig.customTransform) {
              try {
                // 创建增强的执行环境，提供常用的工具函数
                const context = {
                  value: rawValue,
                  // 时间格式化
                  formatTime: (timestamp?: number) => {
                    const date = timestamp ? new Date(timestamp) : new Date();
                    return date.toLocaleTimeString();
                  },
                  formatDate: (timestamp?: number) => {
                    const date = timestamp ? new Date(timestamp) : new Date();
                    return date.toLocaleDateString();
                  },
                  formatDateTime: (timestamp?: number) => {
                    const date = timestamp ? new Date(timestamp) : new Date();
                    return date.toLocaleString();
                  },
                  // 数值格式化
                  formatNumber: (num: number, decimals = 2) => {
                    return Number(num).toFixed(decimals);
                  },
                  formatPercent: (num: number, decimals = 1) => {
                    return (Number(num) * 100).toFixed(decimals) + '%';
                  },
                  // 状态映射
                  mapStatus: (status: any, mapping: Record<string, any>) => {
                    return mapping[status] || status;
                  },
                  // 范围检查
                  inRange: (num: number, min: number, max: number) => {
                    return num >= min && num <= max;
                  },
                  // 字符串操作
                  truncate: (str: string, length: number) => {
                    return str.length > length ? str.substring(0, length) + '...' : str;
                  },
                  // 条件操作
                  when: (condition: boolean, trueValue: any, falseValue: any) => {
                    return condition ? trueValue : falseValue;
                  },
                  // 数学函数
                  Math,
                  // 日期对象
                  Date,
                  // JSON操作
                  JSON
                };

                // 安全执行自定义转换，使用with语句注入上下文
                const func = new Function(
                  'context',
                  `
                with(context) {
                  return ${bindingConfig.customTransform};
                }
              `
                );
                return func(context);
              } catch (error) {
                console.error('Custom transform error:', error);
                return bindingConfig.defaultValue || rawValue;
              }
            }
            return rawValue;

          case 'none':
          default:
            return rawValue;
        }
      } catch (error) {
        console.error('Data transform error:', error);
        return bindingConfig.defaultValue || rawValue;
      }
    });
  };

  /**
   * 应用数据到组件属性
   */
  const applyDataToProperty = (value: any) => {
    if (!bindingConfig.enabled || !bindingConfig.targetProperty) {
      return;
    }

    // 检查更新频率限制
    const now = Date.now();
    if (
      bindingConfig.updateInterval > 0 &&
      now - lastUpdateTime.value < bindingConfig.updateInterval
    ) {
      return;
    }

    let finalValue = transformValue(value);
    lastUpdateTime.value = now;

    // 处理数组数据的更新模式
    if (
      Array.isArray(finalValue) &&
      bindingConfig.updateMode &&
      bindingConfig.updateMode !== 'replace'
    ) {
      const currentData = currentValue.value;

      if (Array.isArray(currentData)) {
        switch (bindingConfig.updateMode) {
          case 'append':
            // 追加模式：在现有数据后面添加新数据
            finalValue = [...currentData, ...finalValue];
            break;
          case 'prepend':
            // 前置模式：在现有数据前面添加新数据
            finalValue = [...finalValue, ...currentData];
            break;
        }

        // 应用数组长度限制
        if (bindingConfig.maxArrayItems && bindingConfig.maxArrayItems > 0) {
          if (bindingConfig.updateMode === 'append') {
            // 追加模式：保留最新的数据（从末尾开始）
            finalValue = finalValue.slice(-bindingConfig.maxArrayItems);
          } else if (bindingConfig.updateMode === 'prepend') {
            // 前置模式：保留最新的数据（从开头开始）
            finalValue = finalValue.slice(0, bindingConfig.maxArrayItems);
          }
        }
      }
    }

    // 更新组件属性
    if (props[bindingConfig.targetProperty] !== undefined) {
      let actualValue = finalValue;

      // 对于hide属性，需要反向转换逻辑
      // 数据绑定中：true=显示，false=隐藏
      // hide属性中：true=隐藏，false=显示
      if (bindingConfig.targetProperty === 'hide') {
        // 先转换为布尔值，然后反向
        const boolValue = Boolean(finalValue);
        actualValue = !boolValue;
      }

      props[bindingConfig.targetProperty] = actualValue;

      // 调用更新回调
      if (onPropertyUpdate) {
        onPropertyUpdate(bindingConfig.targetProperty, actualValue);
      }
    }

    currentValue.value = finalValue;
  };

  /**
   * 更新数据
   */
  const updateData = () => {
    // 数据点ID为空或无效时，直接忽略
    if (
      !bindingConfig.enabled ||
      !bindingConfig.dataPointId ||
      bindingConfig.dataPointId === 'undefined' ||
      bindingConfig.dataPointId.trim() === ''
    ) {
      isConnected.value = false;
      return;
    }

    const dataPoint = realtimeStore.getDataPoint(bindingConfig.dataPointId);

    if (dataPoint && dataPoint.value !== undefined) {
      isConnected.value = true;
      applyDataToProperty(dataPoint.value);
    } else {
      isConnected.value = false;
      // 应用默认值
      if (bindingConfig.defaultValue !== undefined) {
        applyDataToProperty(bindingConfig.defaultValue);
      }
    }
  };

  /**
   * 订阅数据点
   */
  const subscribeToData = () => {
    if (
      bindingConfig.enabled &&
      bindingConfig.dataPointId &&
      bindingConfig.dataPointId !== 'undefined' &&
      bindingConfig.dataPointId.trim() !== ''
    ) {
      realtimeStore.subscribe(bindingConfig.dataPointId, componentId);
    }
  };

  /**
   * 取消订阅
   */
  const unsubscribeFromData = () => {
    if (bindingConfig.dataPointId) {
      realtimeStore.unsubscribe(bindingConfig.dataPointId, componentId);
    }
  };

  // 监听实时数据变化
  watch(
    () => realtimeStore.dataPoints,
    () => {
      updateData();
    },
    { deep: true }
  );

  // 监听消息缓存变化（用于路径式数据点）
  watch(
    () => realtimeStore.getAllCachedMessageData(),
    (newCache, oldCache) => {
      // 当有新消息时，尝试更新数据点（不仅限于路径式）
      if (
        bindingConfig.enabled &&
        bindingConfig.dataPointId &&
        bindingConfig.dataPointId !== 'undefined'
      ) {
        updateData();
      }
    },
    { deep: true, immediate: true }
  );

  // 监听绑定配置变化
  watch(
    () => [
      bindingConfig.enabled,
      bindingConfig.dataPointId,
      bindingConfig.targetProperty,
      bindingConfig.transform
    ],
    (
      [newEnabled, newDataPointId, newTargetProperty, newTransform],
      [oldEnabled, oldDataPointId, oldTargetProperty, oldTransform]
    ) => {
      // 如果数据点ID发生变化，重新订阅
      if (oldDataPointId && newDataPointId !== oldDataPointId) {
        if (oldDataPointId) {
          realtimeStore.unsubscribe(oldDataPointId, componentId);
        }
      }

      // 重新订阅新的数据点
      if (
        newEnabled &&
        newDataPointId &&
        newDataPointId !== 'undefined' &&
        newDataPointId.trim() !== ''
      ) {
        realtimeStore.subscribe(newDataPointId, componentId);
      }

      // 如果启用状态发生变化
      if (oldEnabled !== undefined && newEnabled !== oldEnabled) {
        if (newEnabled) {
          subscribeToData();
        } else {
          unsubscribeFromData();
        }
      }

      updateData();
    },
    { deep: false }
  );

  // 初始化
  onMounted(() => {
    if (bindingConfig.enabled) {
      subscribeToData();
    }
    updateData();
  });

  // 清理
  onUnmounted(() => {
    unsubscribeFromData();
  });

  return {
    // 状态
    currentValue: computed(() => currentValue.value),
    isConnected: computed(() => isConnected.value),

    // 方法
    updateData,
    subscribeToData,
    unsubscribeFromData,
    transformValue,
    applyDataToProperty,

    // 工具函数
    getFormattedValue: () => {
      if (currentValue.value === null || currentValue.value === undefined) {
        return bindingConfig.defaultValue || '--';
      }
      return String(currentValue.value);
    },

    getConnectionStatus: () => {
      return isConnected.value ? 'connected' : 'disconnected';
    }
  };
}

/**
 * 为组件自动应用数据绑定
 * 这是一个便捷函数，适用于大多数场景
 */
export function useAutoDataBinding(
  bindingConfig: IDataBindingConfig | null,
  componentProps: Record<string, any>,
  onPropertyUpdate?: (property: string, value: any) => void
) {
  // 如果没有数据绑定配置，返回一个空的绑定对象
  if (!bindingConfig) {
    return {
      currentValue: computed(() => null),
      isConnected: computed(() => false),
      updateData: () => {},
      subscribeToData: () => {},
      unsubscribeFromData: () => {},
      transformValue: (val: any) => val,
      applyDataToProperty: () => {},
      getFormattedValue: () => '--',
      getConnectionStatus: () => 'disconnected'
    };
  }

  return useDataBinding({
    bindingConfig,
    props: componentProps,
    onPropertyUpdate: (property, value) => {
      // 调用外部提供的更新回调
      if (onPropertyUpdate) {
        onPropertyUpdate(property, value);
      }
    }
  });
}

/**
 * 批量数据绑定处理
 * 支持多个属性绑定到不同的数据点
 */
export function useMultipleDataBinding(
  bindings: Array<{
    config: IDataBindingConfig;
    props: Record<string, any>;
    onUpdate?: (property: string, value: any) => void;
  }>
) {
  const bindingInstances = bindings.map((binding, index) => {
    return useDataBinding({
      bindingConfig: binding.config,
      props: binding.props,
      onPropertyUpdate: binding.onUpdate,
      componentId: `multi-binding-${index}-${Math.random().toString(36).substr(2, 9)}`
    });
  });

  return {
    instances: bindingInstances,

    // 批量更新
    updateAll: () => {
      bindingInstances.forEach((instance) => instance.updateData());
    },

    // 获取所有连接状态
    getConnectionStatuses: () => {
      return bindingInstances.map((instance) => instance.isConnected.value);
    },

    // 获取所有当前值
    getCurrentValues: () => {
      return bindingInstances.map((instance) => instance.currentValue.value);
    }
  };
}
